package com.getpebble.android.framework.protocol.inbound;

import android.content.Context;
import com.getpebble.android.PebbleApplication;
import com.getpebble.android.R;
import com.getpebble.android.bluetooth.protocol.ProtocolMessage;
import com.getpebble.android.common.core.trace.Analytics.MobileAppBehavior;
import com.getpebble.android.common.core.trace.Trace;
import com.getpebble.android.common.core.util.PblPreferences;
import com.getpebble.android.common.core.util.PblPreferences.PrefKey;
import com.getpebble.android.framework.install.Stm32Crc;
import com.getpebble.android.framework.protocol.EndpointId;
import com.getpebble.android.framework.util.ByteUtils;
import com.google.common.primitives.UnsignedInteger;
import com.sun.mail.imap.protocol.ListInfo;
import com.sun.mail.smtp.SMTPMessage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class PblInboundDataloggingMessage extends PblInboundMessage {
    private static final String TAG = PblInboundDataloggingMessage.class.getSimpleName();
    private UUID mAppUuid;
    private Command mCommand;
    private UnsignedInteger mCrc32;
    private ByteBuffer mDataPayload;
    private Datatype mDataType;
    private UnsignedInteger mItemSize;
    private UnsignedInteger mItemsLeftHereafter;
    private UnsignedInteger mLogTag;
    private UnsignedInteger mSessionId;
    private UnsignedInteger mTimestampSecs;

    static /* synthetic */ class AnonymousClass1 {
        static final /* synthetic */ int[] $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Command = new int[Command.values().length];
        static final /* synthetic */ int[] $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Datatype = new int[Datatype.values().length];

        static {
            try {
                $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Datatype[Datatype.BYTE_ARRAY.ordinal()] = 1;
            } catch (NoSuchFieldError e) {
            }
            try {
                $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Datatype[Datatype.UNSIGNED_INTEGER.ordinal()] = 2;
            } catch (NoSuchFieldError e2) {
            }
            try {
                $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Datatype[Datatype.SIGNED_INTEGER.ordinal()] = 3;
            } catch (NoSuchFieldError e3) {
            }
            try {
                $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Command[Command.OPEN_SESSION.ordinal()] = 1;
            } catch (NoSuchFieldError e4) {
            }
            try {
                $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Command[Command.DATA.ordinal()] = 2;
            } catch (NoSuchFieldError e5) {
            }
            try {
                $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Command[Command.CLOSE_SESSION.ordinal()] = 3;
            } catch (NoSuchFieldError e6) {
            }
            try {
                $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Command[Command.TIMEOUT.ordinal()] = 4;
            } catch (NoSuchFieldError e7) {
            }
            try {
                $SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Command[Command.UNKNOWN.ordinal()] = 5;
            } catch (NoSuchFieldError e8) {
            }
        }
    }

    public static abstract class DataItem {
        public abstract byte[] getByteValue();
    }

    public static class ByteDataItem extends DataItem {
        private final byte[] mValue;

        public ByteDataItem(byte[] value) {
            this.mValue = value;
        }

        public byte[] getByteValue() {
            return this.mValue;
        }

        public byte[] getValue() {
            return this.mValue;
        }
    }

    public enum Command {
        OPEN_SESSION((byte) 1),
        DATA((byte) 2),
        CLOSE_SESSION((byte) 3),
        TIMEOUT((byte) 7),
        UNKNOWN((byte) -1);
        
        private byte mCode;

        private Command(byte code) {
            this.mCode = code;
        }

        public byte getCode() {
            return this.mCode;
        }

        public static Command fromCode(byte code) {
            for (Command response : values()) {
                if (response.getCode() == code) {
                    return response;
                }
            }
            return UNKNOWN;
        }
    }

    public enum Datatype {
        BYTE_ARRAY((byte) 0),
        UNSIGNED_INTEGER((byte) 2),
        SIGNED_INTEGER((byte) 3);
        
        private byte mCode;

        private Datatype(byte code) {
            this.mCode = code;
        }

        public byte getCode() {
            return this.mCode;
        }

        public static Datatype fromCode(byte code) {
            for (Datatype response : values()) {
                if (response.getCode() == code) {
                    return response;
                }
            }
            return null;
        }
    }

    public static class InvalidPayloadException extends Exception {
    }

    public static class SignedIntDataItem extends DataItem {
        private final int mValue;
        private final UnsignedInteger mWidth;

        public SignedIntDataItem(int value, UnsignedInteger width) {
            this.mValue = value;
            this.mWidth = width;
        }

        public byte[] getByteValue() {
            switch (this.mWidth.intValue()) {
                case SMTPMessage.RETURN_FULL /*1*/:
                    return new byte[]{Integer.valueOf(this.mValue).byteValue()};
                case SMTPMessage.RETURN_HDRS /*2*/:
                    return ByteUtils.short2bytes((short) this.mValue);
                default:
                    return ByteUtils.int2bytes(this.mValue);
            }
        }

        public int getValue() {
            return this.mValue;
        }
    }

    public static class UnsignedIntDataItem extends DataItem {
        private final UnsignedInteger mValue;
        private final UnsignedInteger mWidth;

        public UnsignedIntDataItem(UnsignedInteger value, UnsignedInteger width) {
            this.mValue = value;
            this.mWidth = width;
        }

        public byte[] getByteValue() {
            switch (this.mWidth.intValue()) {
                case SMTPMessage.RETURN_FULL /*1*/:
                    return new byte[]{this.mValue.byteValue()};
                case SMTPMessage.RETURN_HDRS /*2*/:
                    return ByteUtils.unsignedShort2bytes(this.mValue, ByteOrder.BIG_ENDIAN);
                default:
                    return ByteUtils.unsignedInt2bytes(this.mValue, ByteOrder.BIG_ENDIAN);
            }
        }

        public UnsignedInteger getValue() {
            return this.mValue;
        }
    }

    public PblInboundDataloggingMessage(ProtocolMessage message) {
        super(message);
        ByteBuffer buffer = message.getDataBuffer();
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        byte commandByte = buffer.get();
        this.mCommand = Command.fromCode(commandByte);
        switch (AnonymousClass1.$SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Command[this.mCommand.ordinal()]) {
            case SMTPMessage.RETURN_FULL /*1*/:
                this.mSessionId = ByteUtils.getUint8FromBuffer(buffer);
                this.mAppUuid = ByteUtils.bytes2uuid(buffer);
                this.mTimestampSecs = ByteUtils.getUint32FromBuffer(buffer);
                this.mLogTag = ByteUtils.getUint32FromBuffer(buffer);
                this.mDataType = Datatype.fromCode(buffer.get());
                this.mItemSize = ByteUtils.getUint16FromBuffer(buffer);
                return;
            case SMTPMessage.RETURN_HDRS /*2*/:
                this.mSessionId = ByteUtils.getUint8FromBuffer(buffer);
                this.mItemsLeftHereafter = ByteUtils.getUint32FromBuffer(buffer);
                buffer.mark();
                this.mCrc32 = ByteUtils.getUint32FromBuffer(buffer);
                this.mDataPayload = ByteBuffer.allocate(buffer.remaining());
                this.mDataPayload.put(buffer);
                return;
            case ListInfo.INDETERMINATE /*3*/:
                this.mSessionId = ByteUtils.getUint8FromBuffer(buffer);
                return;
            case R.styleable.WalletFragmentStyle_maskedWalletDetailsHeaderTextAppearance /*5*/:
                Trace.error(TAG, "Unknown command: " + commandByte);
                return;
            default:
                return;
        }
    }

    public Command getCommand() {
        return this.mCommand;
    }

    public UnsignedInteger getSessionId() {
        return this.mSessionId;
    }

    public UUID getAppUuid() {
        return this.mAppUuid;
    }

    public UnsignedInteger getTimestampSecs() {
        return this.mTimestampSecs;
    }

    public UnsignedInteger getLogTag() {
        return this.mLogTag;
    }

    public Datatype getDataType() {
        return this.mDataType;
    }

    public UnsignedInteger getItemSize() {
        return this.mItemSize;
    }

    public List<DataItem> getDataPayload(Datatype dataType, UnsignedInteger itemSize) throws InvalidPayloadException {
        if (Command.DATA.equals(this.mCommand)) {
            int payloadSize = this.mDataPayload.capacity();
            Context appContext = PebbleApplication.getAppContext();
            if (appContext != null && new PblPreferences(appContext).getBooleanData(PrefKey.DATALOGGING_DEBUG, false)) {
                Trace.verbose(TAG, "Incoming datalogging payload. sessionId = " + this.mSessionId + " appUuid = " + this.mAppUuid + " timestamp = " + this.mTimestampSecs + " logTag = " + this.mLogTag + " dataType = " + this.mDataType + " itemSize = " + this.mItemSize + " payload = " + ByteUtils.hexDump(this.mDataPayload.array()));
            }
            this.mDataPayload.position(0);
            this.mDataPayload.order(ByteOrder.LITTLE_ENDIAN);
            int numRecordsStored = payloadSize / itemSize.intValue();
            int remainder = payloadSize % itemSize.intValue();
            if (numRecordsStored <= 0) {
                Trace.warning(TAG, "Invalid numRecordsStored: " + numRecordsStored + " (payloadSize = " + payloadSize + " itemSize = " + itemSize + ")");
                throw new InvalidPayloadException();
            } else if (remainder != 0) {
                Trace.warning(TAG, "Invalid remainder bytes: " + remainder + " (payloadSize = " + payloadSize + " itemSize = " + itemSize + ")");
                throw new InvalidPayloadException();
            } else {
                byte[] payloadBytes = this.mDataPayload.array();
                int dataCrc = new Stm32Crc(false).addBytes(payloadBytes, payloadBytes.length).finalizeCrc();
                if (dataCrc != this.mCrc32.intValue()) {
                    Trace.warning(TAG, "Invalid crc: " + dataCrc + " (expected: " + this.mCrc32.intValue() + ") for bytes: " + ByteUtils.hexDump(payloadBytes) + " (payloadSize = " + payloadSize + " itemSize = " + itemSize + ")");
                    int crcAlt = new Stm32Crc(true).addBytes(payloadBytes, payloadBytes.length).finalizeCrc();
                    Trace.warning(TAG, "... alt crc calc = " + crcAlt);
                    Map<String, Object> dataFields = new HashMap();
                    dataFields.put("receivedCrc", Integer.valueOf(dataCrc));
                    dataFields.put("expectedCrc", Integer.valueOf(this.mCrc32.intValue()));
                    dataFields.put("altCalcCrc", Integer.valueOf(crcAlt));
                    dataFields.put("receivedBytes", ByteUtils.hexDump(payloadBytes));
                    dataFields.put("payloadSize", Integer.valueOf(payloadSize));
                    dataFields.put("itemSize", itemSize);
                    MobileAppBehavior.logDataloggingCrcErrorEvent(dataFields);
                    throw new InvalidPayloadException();
                }
                Trace.verbose(TAG, "CRC OK!: " + dataCrc + " (expected: " + this.mCrc32.intValue() + ")");
                List<DataItem> dataItems = new LinkedList();
                for (int i = 0; i < numRecordsStored; i++) {
                    dataItems.add(getNextDataItem(dataType, itemSize, this.mDataPayload));
                }
                int remainingBytes = this.mDataPayload.remaining();
                if (remainingBytes == 0) {
                    return dataItems;
                }
                Trace.warning(TAG, "Remaining bytes not expected: " + remainingBytes + " (payloadSize = " + payloadSize + " itemSize = " + itemSize + ")");
                throw new InvalidPayloadException();
            }
        }
        Trace.warning(TAG, "Not a data message!");
        throw new InvalidPayloadException();
    }

    private static DataItem getNextDataItem(Datatype dataType, UnsignedInteger itemSize, ByteBuffer dataPayload) throws InvalidPayloadException {
        switch (AnonymousClass1.$SwitchMap$com$getpebble$android$framework$protocol$inbound$PblInboundDataloggingMessage$Datatype[dataType.ordinal()]) {
            case SMTPMessage.RETURN_FULL /*1*/:
                byte[] itemDataBytes = new byte[itemSize.intValue()];
                dataPayload.get(itemDataBytes);
                return new ByteDataItem(itemDataBytes);
            case SMTPMessage.RETURN_HDRS /*2*/:
                UnsignedInteger unsignedInt;
                switch (itemSize.intValue()) {
                    case SMTPMessage.RETURN_FULL /*1*/:
                        unsignedInt = ByteUtils.getUint8FromBuffer(dataPayload);
                        break;
                    case SMTPMessage.RETURN_HDRS /*2*/:
                        unsignedInt = ByteUtils.getUint16FromBuffer(dataPayload);
                        break;
                    case SMTPMessage.NOTIFY_DELAY /*4*/:
                        unsignedInt = ByteUtils.getUint32FromBuffer(dataPayload);
                        break;
                    default:
                        Trace.warning(TAG, "Invalid item size: " + itemSize);
                        throw new InvalidPayloadException();
                }
                return new UnsignedIntDataItem(unsignedInt, itemSize);
            case ListInfo.INDETERMINATE /*3*/:
                int signedInt;
                switch (itemSize.intValue()) {
                    case SMTPMessage.RETURN_FULL /*1*/:
                        signedInt = dataPayload.get();
                        break;
                    case SMTPMessage.RETURN_HDRS /*2*/:
                        signedInt = dataPayload.getShort();
                        break;
                    case SMTPMessage.NOTIFY_DELAY /*4*/:
                        signedInt = dataPayload.getInt();
                        break;
                    default:
                        Trace.warning(TAG, "Invalid item size: " + itemSize);
                        throw new InvalidPayloadException();
                }
                return new SignedIntDataItem(signedInt, itemSize);
            default:
                Trace.warning(TAG, "Invalid data type");
                throw new InvalidPayloadException();
        }
    }

    EndpointId getId() {
        return EndpointId.DATA_LOG;
    }

    protected int getMinSize() {
        return 1;
    }
}
